/*
 * Copyright 2017 the original author or authors.
 */

package com.ivo.sec;


import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ivo.util.WebUtil;

/**
 * <h1>title</h1>
 * <p>
 * content
 * </p>
 * <b>Note:</b>note
 *
 * @author : nexf
 * @since : 2015/10/14 16:37
 */
public abstract class PatternFilter implements Filter {

  public static final String PARAM_NAME_EXCLUSIONS = "exclusions";

  private Set<String> excludesPattern;

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    {
      String exclusions = filterConfig.getInitParameter(PARAM_NAME_EXCLUSIONS);
      if (exclusions != null && exclusions.trim().length() != 0) {
        excludesPattern = new HashSet<>(Arrays.asList(exclusions.split("\\s*,\\s*")));
      }
    }
  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;
    String requestURI = WebUtil.getRelativeURI(httpRequest);

    if (isExclusion(requestURI)) {
      chain.doFilter(request, response);
      return;
    }
    try {
      preFilter(httpRequest, httpResponse, chain);
      chain.doFilter(request, response);
    } finally {
      afterFilter(httpRequest, httpResponse, chain);
    }


  }

  protected void afterFilter(HttpServletRequest request, HttpServletResponse response,
      FilterChain chain) {
  }

  protected abstract void preFilter(HttpServletRequest request, HttpServletResponse response,
      FilterChain chain);


  @Override
  public void destroy() {

  }

  public boolean isExclusion(String requestURI) {
    if (excludesPattern == null) {
      return false;
    }

    for (String pattern : excludesPattern) {
      if (WebUtil.matches(pattern, requestURI)) {
        return true;
      }
    }

    return false;
  }

}
